// 导入 express 模块
const express = require('express')

//在路由之前导入
const joi = require('joi')

// 创建 express 的服务器实例
const app = express()

// 导入 cors 中间件
const cors = require('cors')
// 将 cors 注册为全局中间件
app.use(cors())

// 设置跨域和相应数据格式
app.all('*', function (req, res, next) {
	res.header('Access-Control-Allow-Origin', '*')
	res.header(
		'Access-Control-Allow-Headers',
		'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild'
	)
	res.header(
		'Access-Control-Allow-Methods',
		'PUT, POST, GET, DELETE, OPTIONS'
	)
	if (req.method == 'OPTIONS') {
		res.cc('可以跨域', 0, true) /* 让options请求快速返回*/
	} else {
		next()
	}
})

//配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))

// 通过 express.json() 这个中间件，解析表单中的 JSON 格式的数据
app.use(express.json())

//为了验证码能通过，则需要导入session组件
const session = require('express-session')
// 配置session中间件
app.use(
	session({
		secret: 'keyboard cat', //服务端生成申明可随意写
		resave: true, //强制保存session即使他没有什么变化
		saveUninitialized: true, //强制将来初始化的session存储
	})
)

// app.get('/put', (req, res) => {
// 	req.session.username = 'zhangshan'
// 	res.send('设置cookie成功！')
// })

// app.get('/get', (req, res) => {
// 	console.log(req.session.username)
// 	res.send('获取cookie成功！')
// })

// 定义send的响应数据的中间件
app.use(function (req, res, next) {
	// status = 0 为成功； status = 1 为失败； 默认将 status 的值设置为 1，方便处理失败的情况
	res.cc = function (err, status = 1, success = false) {
		res.send({
			success,
			// 状态
			status,
			// 状态描述，判断 err 是 错误对象 还是 字符串
			message: err instanceof Error ? err.message : err,
		})
	}
	next()
})

// 导入配置文件
const config = require('./config')

// 解析 token 的中间件
const { expressjwt: expressJWT } = require('express-jwt')

// 使用 .unless({ path: [/^\/api\//] }) 指定哪些接口不需要进行 Token 的身份认证
app.use(
	expressJWT({ secret: config.jwtSecretKey, algorithms: ['HS256'] }).unless({
		path: [/^\/api\//],
	})
)

// 导入并使用文章分类路由模块
const artCateRouter = require('./router/artcate')
// 为文章分类的路由挂载统一的访问前缀 /my/article
app.use('/my/article', artCateRouter)

// 导入并使用用户信息路由模块
const userinfoRouter = require('./router/userinfo')
// 注意：以 /my 开头的接口，都是有权限的接口，需要进行 Token 身份认证
app.use('/my', userinfoRouter)

// 导入并使用文章路由模块
const articleRouter = require('./router/article')
// 为文章的路由挂载统一的访问前缀 /my/article
app.use('/my/article', articleRouter)

// 托管静态资源文件
app.use('/uploads', express.static('./uploads'))

// 导入并注册用户路由模块
const userRouter = require('./router/user')
app.use('/api', userRouter)

// 错误中间件
app.use(function (err, req, res, next) {
	// 数据验证失败
	if (err instanceof joi.ValidationError) return res.cc(err)
	// 捕获身份认证失败的错误
	// console.log(err)
	// console.log(req.headers.authorization)
	if (err.name === 'UnauthorizedError') return res.cc('身份认证失败！')

	// 未知错误
	res.cc(err)
})

// 调用 app.listen 方法，指定本地端口号8080 启动web服务器
let server = app.listen(8080, function () {
	console.log('api server running at http://127.0.0.1:8080')
})

/**
 *下面测试通信功能
 */
var io = require('socket.io').listen(server)
//socket连接
//socket连接
io.on('connection', (socket) => {
	console.log('a user connected')
	// socket.broadcast.emit('newPeer','new');
	//将收到的消息广播出去
	socket.on('sendMessage', function (content) {
		console.log(content) //content为收到的消息内容，包括姓名和消息内容
		socket.broadcast.emit('getMessage', content)
	})

	//监听新人连接，然后广播出去
	socket.on('newPeople', function (name) {
		console.log(name) //name为连接者的姓名或昵称
		socket.broadcast.emit('newPeer', name)
	})
})

//将vue项目打包成h5后，发起请求将html文件返回
app.get('/socket', (req, res) => {
	res.sendfile('./index.html')
})
